// import {
//   Glodon,
//   BimfaceSDKLoader,
//   BimfaceSDKLoaderConfig,
// } from './BimfaceSDKLoader.module.js';
import { Camera } from './Camera.js';
import Marker from './Marker.js';
import { Misc } from './Misc.js';
import Tools from './Tools/index.js';
import Layer from './Layer.js';
import VGE from '../../VGE';

const GEOGSYSTEM = 'EPSG:4490';
const PROJSYSTEM = 'CGCS_GK_116';

/**
 * 模型浏览入口
 */
export default class BFaceApp {
	static async open(sceneData = {}, callback) {
		try {
			const { container, cameraParams, homeView, token: viewToken } = sceneData;
			const options = new BimfaceSDKLoaderConfig();
			options.viewToken = viewToken;
			console.log(sceneData, '----sceneData');
			const viewMetaData = await BimfaceSDKLoader.load(options);
			if (!viewMetaData.viewType === '3DView') {
				return null;
			}
			const webAppConfig = new Glodon.Bimface.Application.WebApplication3DConfig();
			// webAppConfig.domElement = container;
			const dom = await VGE.util.findOrCreateDom(container, true, true);
			webAppConfig.domElement = dom;
			webAppConfig.orbitButton = Glodon.Bimface.Viewer.OrbitButton.Right;
			const app = (this.app = new Glodon.Bimface.Application.WebApplication3D(webAppConfig));
			app.addView(viewToken);
			const viewer = (this.viewer = app.getViewer());

			viewer.addEventListener(Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded, () => {
				callback && callback();

				this.camera = new Camera(viewer);
				this.tools = Tools(viewer);
				this.marker = new Marker(viewer);
				this.misc = new Misc(viewer);
				this.layer = new Layer(viewer);

				const info = this.viewer
					.getViewer()
					.getModelManager()
					.getModel(this.viewer.getModel().modelId)._config;
				const projCS = info.coordinateSystem?.projCS;
				const geogCS = info.coordinateSystem?.geogCS;
				if (projCS || geogCS) {
					const convertor = new Glodon.Bimface.Common.CoordinateConvertor();
					convertor.defineCustomCoordSys(PROJSYSTEM, {
						falseEasting: 500000,
						centralMeridian: 116
					});
					const convertToPosition = (latLon) => {
						const position = convertor.translateLatLon(latLon, GEOGSYSTEM, PROJSYSTEM);
						position.z = latLon.height || 0;
						return position;
					};
					if (projCS) {
						const { epsg, EPSG, centralMeridian, falseEasting, offset } = projCS;
						let x = 0,
							y = 0,
							z = 0;
						if (offset) {
							x = offset[0] || 0;
							y = offset[1] || 0;
							z = offset[2] || 0;
						}
						let originProjName;
						if (centralMeridian) {
							originProjName = 'custom';
							convertor.defineCustomCoordSys(originProjName, { falseEasting, centralMeridian });
						} else {
							originProjName = `EPSG:${epsg || EPSG}`;
						}

						if (x !== undefined && y !== undefined) {
							let latLon = convertor.translateXY({ x, y }, originProjName, GEOGSYSTEM);
							const projectedOriginPosition = convertToPosition(latLon);
							viewer._projectedOriginPosition = new THREE.Vector3(
								projectedOriginPosition.x,
								projectedOriginPosition.y,
								z
							);
						}
					} else {
						const { origin, altitude, latLon } = geogCS;
						const projectedOriginPosition = convertToPosition({
							lat: latLon[0],
							lon: latLon[1]
						});
						viewer._projectedOriginPosition = new THREE.Vector3(
							projectedOriginPosition.x - origin[0],
							projectedOriginPosition.y - origin[1],
							-origin[2]
						);
						if (!isNaN(altitude)) {
							viewer._projectedOriginPosition.z = altitude;
						}
					}

					viewer._getPositionByLatLon = (latLon) => {
						const position = convertToPosition(latLon);
						return {
							x: position.x - viewer._projectedOriginPosition.x,
							y: position.y - viewer._projectedOriginPosition.y,
							z: latLon.height ? latLon.height : viewer._projectedOriginPosition.z
						};
					};
					viewer._getLatLonByPosition = (position) => {
						const projPosition = {
							x: position.x + viewer._projectedOriginPosition.x,
							y: position.y + viewer._projectedOriginPosition.y,
							z: position.z + viewer._projectedOriginPosition.z
						};
						const convertor = new Glodon.Bimface.Common.CoordinateConvertor();
						const latLon = convertor.translateXY(projPosition, PROJSYSTEM, GEOGSYSTEM);
						return latLon;
					};

					if (cameraParams) {
						const status = this.camera.getCameraStatusFromParams(cameraParams);
						console.log(status, 'status');
						this.viewer.getViewer().setCamera(JSON.stringify(status), false, undefined, true);
						this.camera.addEventListener();
					}
					if (homeView) {
						const status = this.camera.getCameraStatusFromParams(homeView);
						this.viewer.recordCustomHomeview(status);
					}
				} else {
					this.viewer._withoutLatLon = true;
				}

				viewer.render();
			});
			return viewer;
		} catch (e) {
			console.error(e?.message ? e.message : e);
		}
	}

	static async close() {
		try {
			if (this.app) {
				this.app.destroy();
				this.app = null;
				this.viewer = null;
			}
		} catch (e) {
			console.error(e?.message ? e.message : e);
		}
	}
}

BFaceApp.camera = null;
BFaceApp.tools = null;
BFaceApp.marker = null;
BFaceApp.layer = null;
BFaceApp.misc = null;
